package edu.washington.ling.syntric.io;

import java.io.RandomAccessFile;
import java.io.IOException;
import java.util.List;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TreeFileReaderFlatMultiline extends TreeFileReader {
	
	private RandomAccessFile f;
	private ArrayList<Long> treeLocations;
	private Iterator<Long> treeLocationIter;
	
	public TreeFileReaderFlatMultiline(String path, String layer) throws IOException {
		super(path, layer);
		f = new RandomAccessFile(path, "r");
		treeLocations = new ArrayList<Long>();
		boolean beforeFirstTree = true;
		boolean afterBlankLine = false;
		Long location = 0L;
		String line = null;
		while ((line = f.readLine()) != null) {
			if (line.length() > 0 && (beforeFirstTree || afterBlankLine )) {
				treeLocations.add(location);
				beforeFirstTree = false;
				afterBlankLine = false;
			}
			else if (line.length() == 0){
				afterBlankLine = true;
			}
			location = f.getFilePointer();
		}
		treeLocationIter = treeLocations.iterator();
	}
	@Override
	public int numTrees() {
		return treeLocations.size();
	}
	@Override
	public Set<String> getIDs() {
		Set<String> treeIDs = new TreeSet<String>();
		for (int i = 0; i < treeLocations.size(); i++) {
			treeIDs.add(Integer.toString(i));
		}
		return treeIDs;
	}
	@Override
	public TreeRepresentation readNextTreeRep() throws IOException {
		TreeRepresentation treeRep = null;
		if (treeLocationIter.hasNext()) {
			Long location = treeLocationIter.next();
			f.seek(location.longValue());
			List<String> lines = new LinkedList<String>();
			String line = null;
			while ((line = f.readLine()) != null){
				if (line.length() > 0) {
					lines.add(line);
				} 
				else { break; }
			}
			if (lines.size() > 0) {
				treeRep = new TreeRepresentation(lines, this.getLayer());
			}
		}
		return treeRep;
	}
	
	@Override
	public boolean hasTreeRepWithID(String id) {
		boolean hasTreeRepWithID = false;
		int tNum = Integer.parseInt(id);
		if (tNum <= treeLocations.size()) {
			hasTreeRepWithID = true;
		}
		return hasTreeRepWithID;
	}
	
	@Override
	public TreeRepresentation readTreeRepWithID(String id) throws IOException {
		TreeRepresentation treeRep = null;
		int tNum = Integer.parseInt(id);
		Long location = treeLocations.get(tNum - 1);
		f.seek(location.longValue());
		List<String> lines = new LinkedList<String>();
		String line = null;
		while ((line = f.readLine()) != null){
			if (line.length() > 0) {
				lines.add(line);
			} 
			else { break; }
		}
		if (lines.size() > 0) {
			treeRep = new TreeRepresentation(lines, this.getLayer());
		}
		return treeRep;
	}
}
